import React, {
  useState,
  useMemo,
  useEffect,
  useCallback,
  useRef,
} from 'react';
import { connect } from 'dva';
import { ActionCreators, StateWithHistory } from 'redux-undo';
import Calibration from '@/components/Calibration';
import CollapsedHandler from '@/components/CollapsedHandler';
import MenuTabs from '@/components/MenuTabs';
import FormRender from '@/renderer/FormRender';
import EditorHeader from './EditorHeader';
import ResourceLibrary from './ResourceLibrary';
import ComponentLibrary from './ComponentLibrary';
import DropSource from './DropSource';
import { Category, ComptTplType } from '@/ui-components/common';
import { Tabs, Result } from 'antd';
import './index.less';
import uiCompt from '@/ui-components/index';
import { computedFitRatio } from '@/utils/tool';

function Container(props: {
  history?: any;
  location?: any;
  pstate?: any;
  dispatch?: any;
  onReview?: Function;
}) {
  const [rightColla, setRightColla] = useState(false); // 属性面板折叠
  const [bottomColla, setBottomColla] = useState(false); // 页面管理折叠

  // 指定画布的id
  let canvasId = 'js_canvas';

  // 编辑区区域
  const edtiorArea = useRef<HTMLDivElement>(null);

  const [edtiorAreaSize, setEditorAreaSize] = useState<{
    width: number;
    height: number;
  }>({ width: 0, height: 0 });

  const [editorSize, setEditorSize] = useState<{
    width: number;
    height: number;
  }>({ width: 0, height: 0 });

  const { pstate, dispatch } = props;
  const curPoint = pstate ? pstate.curPoint : {};
  const pointData = pstate ? pstate.pointData : [];
  const pageData = pstate ? pstate.pageData : {};
  const { width: iWidth, height: iHeight, bgImg } = pageData;

  const { onReview } = props;

  const { width: eWidth, height: eHeight } = edtiorAreaSize;

  const { componentLibraryTpl, resourceLibraryTpl, schemaH5 } = uiCompt;

  const allType = useMemo(() => {
    let arr: string[] = [];
    resourceLibraryTpl.forEach((v: { component: string }) => {
      arr.push(v.component);
    });
    componentLibraryTpl.forEach((v: { component: string }) => {
      arr.push(v.component);
    });
    return arr;
  }, [resourceLibraryTpl, componentLibraryTpl]);

  const generateSubTabs = useMemo(() => {
    const tabMap = {
      resourceLibrary: resourceLibraryTpl,
      componentLibrary: componentLibraryTpl,
    };
    return (tab: { key: Category; name: string }) => {
      const { key, name } = tab;
      const tpls: ComptTplType[] = (tabMap as any)[key];
      switch (key) {
        case 'componentLibrary':
          return (
            <ComponentLibrary
              name={name}
              components={tpls}
              canvasId={canvasId}
            />
          );
        default:
          return (
            <ResourceLibrary
              name={name}
              components={tpls}
              canvasId={canvasId}
              allType={allType}
            />
          );
      }
    };
  }, [schemaH5]);

  const Menus = useMemo(
    () => [
      {
        key: 'resourceLibrary',
        name: '资源库',
        icon: 'icon-ziyuanku',
        children: generateSubTabs({ name: '资源库', key: 'resourceLibrary' }),
      },
      {
        key: 'componentLibrary',
        name: '组件',
        icon: 'icon-zujian',
        children: generateSubTabs({ name: '组件', key: 'componentLibrary' }),
      },
    ],
    [generateSubTabs],
  );

  const redohandler = useMemo(() => {
    return () => {
      dispatch(ActionCreators.redo());
    };
  }, [dispatch]);

  const undohandler = useMemo(() => {
    return () => {
      dispatch(ActionCreators.undo());
    };
  }, [dispatch]);

  const clearData = useCallback(() => {
    dispatch({ type: 'editorModel/clearAll' });
  }, [dispatch]);

  const handleFormSave = useMemo(() => {
    // 表单编辑后更新pointData
    return (data: any) => {
      const enableResizing = curPoint.item.enableResizing;
      const { fontSize } = data;
      const point = enableResizing
        ? curPoint.point
        : { ...curPoint.point, w: fontSize, h: fontSize };
      dispatch({
        type: 'editorModel/modPointData',
        payload: {
          ...curPoint,
          item: { ...curPoint.item, config: data },
          point,
        },
      });
    };
  }, [curPoint, dispatch]);

  const handleDel = useMemo(() => {
    return (id: any) => {
      dispatch({
        type: 'editorModel/delPointData',
        payload: { id },
      });
    };
  }, [dispatch]);

  const attributeRender = useMemo(() => {
    console.log(curPoint);
    return (
      <>
        <div className="pl16 h52 fsz14 flex items-center text-color bdb1">
          属性
        </div>
        <div className="flex1 pt16 overflow-y-auto overflow-x-hidden">
          {curPoint?.item && (
            <FormRender
              config={curPoint.item.editableData}
              uid={curPoint.id}
              defaultValue={curPoint.item.config}
              onSave={handleFormSave}
              onDel={handleDel}
              // rightPannelRef={ref}
            />
          )}
        </div>
      </>
    );
  }, [handleFormSave, handleDel, curPoint]);

  const rightRender = useMemo(() => {
    return (
      <div className="flex flex-col flex1 h100p overflow-hidden">
        {pointData.length && curPoint?.item ? (
          attributeRender
        ) : (
          <div className="w100p h52 flex items-center text-color">
            <Tabs className="attrTabs">
              <Tabs.TabPane key="pageAttr" tab="页面属性"></Tabs.TabPane>
              <Tabs.TabPane
                key="textBasicInfo"
                tab="课本基本属性"
              ></Tabs.TabPane>
            </Tabs>
          </div>
        )}
      </div>
    );
  }, [curPoint, pointData.length, attributeRender]);

  useEffect(() => {
    if (pstate.curPoint && pstate.curPoint.status === 'inToCanvas') {
      setRightColla(false);
    }
  }, [pstate.curPoint]);

  useEffect(() => {
    if (edtiorArea?.current) {
      const { clientWidth: width, clientHeight: height } = edtiorArea.current;
      setEditorAreaSize({ width, height });
    }
  }, [edtiorArea]);

  const getScale = () => {
    const fitRatio = computedFitRatio(iWidth, iHeight, eWidth, eHeight);
    dispatch({
      type: 'editorModel/modPageData',
      payload: { scale: fitRatio },
    });
    setEditorSize({
      width: Math.round(iWidth * fitRatio),
      height: Math.round(iHeight * fitRatio),
    });
  };

  useEffect(() => {
    if (iWidth && iHeight && eWidth && eHeight) {
      getScale();
    }
  }, [iWidth, iHeight, eWidth, eHeight]);

  const editorRender = useMemo(() => {
    const { width, height } = editorSize;
    return (
      <div className="relative flex-center w100p h100p">
        {width && height && (
          <div
            className="background-color-white"
            style={{
              width,
              height,
              backgroundImage: `url(${bgImg})`,
              backgroundSize: 'contain',
            }}
          >
            <DropSource canvasId={canvasId} allType={allType} />
          </div>
        )}
      </div>
    );
  }, [editorSize, bgImg, canvasId, allType]);
  return (
    <>
      <EditorHeader
        redohandler={redohandler}
        undohandler={undohandler}
        pointData={pointData}
        pageData={pageData}
        clearData={clearData}
        location={props.location}
        onReview={onReview}
      />
      <div
        className="relative flex w100p overflow-hidden"
        style={{
          height: `calc(100% - ${bottomColla ? '60' : '197'}px)`,
          transition: 'all ease-in-out 0.5s',
        }}
      >
        {/* 左侧 */}
        <div
          className="flex h100p"
          style={{
            width: '352px',
          }}
        >
          <MenuTabs tabs={Menus} />
        </div>
        {/* 中间编辑区 */}
        <div className="flex1" ref={edtiorArea}>
          {editorRender}
        </div>
        {/* 右侧 */}
        <div
          className="bg-panel flex h100p"
          style={{
            transition: 'all ease-in-out 0.5s',
            transform: rightColla ? 'translate(284px,0)' : 'translate(0,0)',
            width: '296px',
          }}
        >
          <CollapsedHandler
            align="vertical"
            isCollapsed={rightColla}
            onToggle={() => setRightColla((rightColla) => !rightColla)}
          />
          {rightRender}
        </div>
      </div>
      {/* 底部 */}
      <div className="relative">
        <CollapsedHandler
          align="horizontal"
          direction="bottom"
          isCollapsed={bottomColla}
          onToggle={() => setBottomColla((bottomColla) => !bottomColla)}
        />
        <div className="bg-panel" style={{ height: 135 }}></div>
      </div>
    </>
  );
}

export default connect((state: StateWithHistory<any>) => {
  return {
    pstate: state.present.editorModel,
  };
})(Container);
